package com.mjk.common.ai.service;


import com.github.pagehelper.Page;
import com.mjk.common.ai.dto.AiModelDto;
import com.mjk.common.ai.dto.AiModelSearchReq;
import com.mjk.common.ai.entity.AiModel;
import com.mjk.common.ai.enums.ErrorEnum;
import com.mjk.common.ai.exception.BaseException;
import com.mjk.common.ai.util.MPPageUtil;
import com.mjk.common.core.jdbc.bean.BeePage;
import com.mjk.common.core.jdbc.service.plus.idbservice.BeeDBService;
import com.mjk.common.core.jdbc.service.plus.wrap.BeeQueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class AiModelService {

    @Autowired
    private BeeDBService beeDBService;
    @Resource
    private AiModelSettingService aiModelSettingService;

    public void init() {
        BeeQueryWrapper wrapper = new BeeQueryWrapper(AiModel.class);
        wrapper.eq(AiModel::getIsDeleted, false);
        List<AiModel> aiModels = beeDBService.findManyByWrapper(wrapper);
        aiModelSettingService.init(aiModels);
    }

    public List<AiModel> listBy(String platform, String type) {
        BeeQueryWrapper wrapper = new BeeQueryWrapper(AiModel.class);
        wrapper.eq(AiModel::getIsDeleted, false)
                .eq(AiModel::getPlatform, platform)
                .eq(AiModel::getType, type);
        return beeDBService.findManyByWrapper(wrapper);
    }

    public AiModel getByName(String modelName) {
        BeeQueryWrapper wrapper = new BeeQueryWrapper(AiModel.class);
        wrapper.eq(AiModel::getIsDeleted, false)
                .eq(AiModel::getName, modelName);
        return (AiModel) beeDBService.findOneByWrapper(wrapper);
    }

    public AiModel getByNameOrThrow(String modelName) {
        BeeQueryWrapper wrapper = new BeeQueryWrapper(AiModel.class);
        wrapper.eq(AiModel::getIsDeleted, false)
                .eq(AiModel::getName, modelName);
        AiModel aiModel = (AiModel) beeDBService.findOneByWrapper(wrapper);

        if (null == aiModel) {
            throw new BaseException(ErrorEnum.A_MODEL_NOT_FOUND);
        }
        return aiModel;
    }

    public Long getIdByName(String modelName) {
        AiModel aiModel = this.getByName(modelName);
        return null == aiModel ? 0L : aiModel.getId();
    }

    public AiModel getByIdOrThrow(Long id) {
        BeeQueryWrapper wrapper = new BeeQueryWrapper(AiModel.class);
        wrapper.eq(AiModel::getId, id);
        AiModel existModel = (AiModel) beeDBService.findOneByWrapper(wrapper);
        if (null == existModel) {
            throw new BaseException(ErrorEnum.A_MODEL_NOT_FOUND);
        }
        return existModel;
    }

    public BeePage<AiModelDto> search(AiModelSearchReq aiModelSearchReq, Integer currentPage, Integer pageSize) {
        BeeQueryWrapper wrapper = new BeeQueryWrapper(AiModel.class);
        if (StringUtils.isNotBlank(aiModelSearchReq.getPlatform())) {
            wrapper.eq(AiModel::getPlatform, aiModelSearchReq.getPlatform());
        }
        if (StringUtils.isNotBlank(aiModelSearchReq.getType())) {
            wrapper.eq(AiModel::getType, aiModelSearchReq.getType());
        }
        if (null != aiModelSearchReq.getIsEnable()) {
            wrapper.eq(AiModel::getIsEnable, aiModelSearchReq.getIsEnable());
        }
        wrapper.eq(AiModel::getIsDeleted, false);
        wrapper.orderByAsc(AiModel::getUpdateTime);
        wrapper.setPage(currentPage, pageSize);
        BeePage<AiModel> aiModelPage = beeDBService.findManyByWrapperWithPage(wrapper);
        return MPPageUtil.convertToPage(aiModelPage, new BeePage<>(), AiModelDto.class);
    }

    public void disable(Long id) {
        AiModel model = new AiModel();
        model.setId(id);
        model.setIsEnable(false);
        BeeQueryWrapper wrapper = new BeeQueryWrapper(model);
        wrapper.eq(AiModel::getId, model.getId());
        beeDBService.update(wrapper);
    }

    public void enable(Long id) {
        AiModel model = new AiModel();
        model.setId(id);
        model.setIsEnable(true);
        BeeQueryWrapper wrapper = new BeeQueryWrapper(model);
        wrapper.eq(AiModel::getId, model.getId());
        beeDBService.update(wrapper);
    }

    public List<AiModelDto> listEnable() {
        BeeQueryWrapper wrapper = new BeeQueryWrapper(AiModel.class);
        wrapper.eq(AiModel::getIsEnable, true)
                .eq(AiModel::getIsDeleted, false);
        List<AiModel> aiModels = beeDBService.findManyByWrapper(wrapper);
        return MPPageUtil.convertToList(aiModels, AiModelDto.class);
    }

    public AiModelDto addOne(AiModelDto aiModelDto) {
        BeeQueryWrapper wrapper = new BeeQueryWrapper(AiModel.class);
        wrapper.eq(AiModel::getName, aiModelDto.getName())
                .eq(AiModel::getPlatform, aiModelDto.getPlatform())
                .eq(AiModel::getIsDeleted, false);
        int count = beeDBService.countByWrapper(wrapper);
        if (count > 0) {
            throw new BaseException(ErrorEnum.A_MODEL_ALREADY_EXIST);
        }
        AiModel aiModel = new AiModel();
        BeanUtils.copyProperties(aiModelDto, aiModel);
        beeDBService.insert(aiModel);

        AiModelDto result = new AiModelDto();
        BeanUtils.copyProperties(aiModel, result);

        aiModelSettingService.addOrUpdate(aiModel);

        return result;
    }

    public void edit(AiModelDto aiModelDto) {
        AiModel oldAiModel = getByIdOrThrow(aiModelDto.getId());

        AiModel aiModel = new AiModel();
        BeanUtils.copyProperties(aiModelDto, aiModel, "createTime", "updateTime");
        BeeQueryWrapper wrapper = new BeeQueryWrapper(aiModel);
        wrapper.eq(AiModel::getId, aiModel.getId());
        beeDBService.update(wrapper);

        AiModel updatedOne = getByIdOrThrow(aiModelDto.getId());
        aiModelSettingService.delete(oldAiModel);
        aiModelSettingService.addOrUpdate(updatedOne);
    }

    public void softDelete(Long id) {
        AiModel existModel = getByIdOrThrow(id);

        AiModel model = new AiModel();
        model.setId(id);
        model.setIsDeleted(true);
        BeeQueryWrapper wrapper = new BeeQueryWrapper(model);
        wrapper.eq(AiModel::getId, model.getId());
        beeDBService.update(wrapper);

        aiModelSettingService.delete(existModel);
    }
}
